class unionset
{
public:
    unordered_map<string, string> fa;
    unionset(vector<string>& temp)
    {
        for (auto& x : temp) fa[x] = x;
    }
    string find(string s)
    {
        return fa[s] == s ? s : fa[s] = find(fa[s]);
    }
    void merge(string a, string b)
    {
        fa[find(a)] = find(b);
    }
    int num()
    {
        int ans = 0;
        for (auto& x : fa)
        {
            if (!x.first.compare(x.second)) ans += 1;
        }
        return ans;
    }
};

class Solution {
public:
    int slove(string a, string b)
    {
        int num = 0;
        for (int i = 0; i < b.size(); i++)
        {
            if (a[i] != b[i]) num += 1;
            if (num > 2) return 0;
        }
        return 1;
    }
    int numSimilarGroups(vector<string>& strs) {
        unionset s(strs);
        for (int i = 0; i < strs.size(); i++)
        {
            for (int j = i + 1; j < strs.size(); j++)
            {
                if (slove(strs[i], strs[j])) s.merge(strs[i], strs[j]);
            }
        }
        return s.num();
    }
};